package com.abe.libquick.base.viewmodel;

import android.app.Application;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.abe.libcore.utils.CommonUtils;
import com.abe.libquick.utils.quick.EmptyUtils;

import java.util.Locale;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class BaseVM extends AndroidViewModel {

    protected MutableLiveData<VMLoadEntity> loadData = new MutableLiveData<>();

    protected VMLoadEntity normalLoad(boolean show) {
        return new VMLoadEntity(show, "Loading...", VMLoadEntity.NORMAL_LOAD);
    }

    public BaseVM(@NonNull Application application) {
        super(application);
        loadData.setValue(normalLoad(false));
    }

    public LiveData<VMLoadEntity> loadData() {
        return loadData;
    }

    public abstract class SimDataCallback<T> extends SimCallback<T> {

        public SimDataCallback() {
            super();
        }

        public SimDataCallback(String TAG) {
            super(TAG);
        }

        public SimDataCallback(String TAG, SimLoadTips tips) {
            super(TAG, tips);
        }

        @Override
        public void onError(String flag, String msg) {

        }

        @Override
        public void onFinish() {

        }
    }

    public abstract class SimCallback<T> implements Callback<T> {

        private final String TAG;
        private final SimLoadTips loadTips;

        public SimCallback() {
            this(BaseVM.this.getClass().getSimpleName());
        }

        public SimCallback(String TAG) {
            this(TAG, new NormalLoadTips());
        }

        public SimCallback(String TAG, SimLoadTips tips) {
            this.TAG = TAG;
            this.loadTips = tips;
            if (loadTips != null) loadTips.onLoadStart();
        }

        public abstract void onResult(T data);

        public abstract void onError(String flag, String msg);

        public abstract void onFinish();

        @Override
        public void onResponse(@NonNull Call<T> call, @NonNull Response<T> response) {
            T data = response.body();
            if (EmptyUtils.isNotEmpty(data)) {
                onResult(response.body());
            } else {
                CommonUtils.INSTANCE.log(String.format("%s-error:null", TAG));
                onError(TAG, "error-null");
            }
            onFinish();
            if (loadTips != null) loadTips.onLoadEnd();
        }

        @Override
        public void onFailure(@NonNull Call<T> call, @NonNull Throwable t) {
            CommonUtils.INSTANCE.log(String.format(Locale.CANADA, "%s-error:%s", TAG, t.getMessage()));
            onError(TAG, String.format(Locale.CHINA, "error-%s", t.getMessage()));
            onFinish();
            if (loadTips != null) loadTips.onLoadEnd();
        }
    }

    public class NormalLoadTips implements SimLoadTips {

        @Override
        public void onLoadStart() {
            loadData.setValue(normalLoad(true));
        }

        @Override
        public void onLoadEnd() {
            loadData.setValue(normalLoad(false));
        }
    }

    public interface SimLoadTips {
        void onLoadStart();

        void onLoadEnd();
    }
}